// @algorithm @lc id=8 lang=cpp
// @title string-to-integer-atoi

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include "algm/algm.h"
using namespace std;
// @test("42")=42
// @test("   -42")=-42
// @test("4193 with words")=4193

/**
 * @brief
 * 本题可以用自动状态机来解. 只要了解如何表示这个自动机, 那么每次输入都会使自动状态机的状态发生跳转, 那么最后输出状态机当前的状态即可.
 */

const long long KMaxInt = 2147483647;
const long long kMinInt = 2147483648;

class AutoMation {
public:
    int getState(const char ch)
    {
        if (ch == ' ')
            return 0;
        else if (ch == '+' || ch == '-')
            return 1;
        else if (ch >= '0' && ch <= '9')
            return 2;
        else
            return 3;
    }

    void push(const char ch)
    {
        state = states[state][getState(ch)];
        if (state == "number") {
            int number = (int)(ch - '0');
            res        = sign == 1 ? std::min(res * 10 + number, KMaxInt) : std::min(res * 10 + number, kMinInt);
        } else if (state == "sign")
            sign = ch == '-' ? -1 : 1;
    }

    int pullResult()
    {
        return sign * res;
    }

    long long                             res    = 0;
    long long                             sign   = 1;
    string                                state  = "begin";
    unordered_map<string, vector<string>> states = { { "begin", { "begin", "sign", "number", "end" } }, { "sign", { "end", "end", "number", "end" } }, { "number", { "end", "end", "number", "end" } }, { "end", { "end", "end", "end", "end" } } };
};

class Solution {
public:
    int myAtoi(string str)
    {
        AutoMation auto_mation;
        for (auto it = str.begin(); it != str.end(); it++)
            auto_mation.push(*it);
        return auto_mation.pullResult();
    }
};